package com.controller.sys;


import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.common.base.BaseConstant;
import com.common.base.BaseController;
import com.common.log.Log;
import com.common.util.*;
import com.entity.sys.SysUser;
import com.entity.sys.query.SysQuery;
import com.service.sys.SysSafeService;
import com.service.sys.SysUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户信息
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController extends BaseController<SysUserService,SysUser> {

    @Resource
    private SysSafeService sysSafeService;
    @Value("${filePath}")
    private String path;

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/getLoginUser")
    public ResultUtil getLoginUser() {
        Map<String,Object> map = new HashMap<>();
        SysUser user = service.getCurrentUser();
        //判断密码是否过了有效期
        if (user.getUpdatePwdTime() == null){
            SysUser byId = service.getById(user.getId());
            user.setUpdatePwdTime(byId.getUpdatePwdTime());
        }
        sysSafeService.getPwdCycle(map,user.getUpdatePwdTime());
        map.put("user",user);
        map.put("permissions",StpUtil.getPermissionList());
        return ResultUtil.success(map);
    }

    /**
     * 用户列表
     */
    @GetMapping("/list")
    @SaCheckPermission("system:user:view")
    public ResultUtil list(SysQuery query) {
        return ResultUtil.success(service.page(query));
    }

    /**
     * 根据id获取用户
     */
    @GetMapping("/getById/{id}")
    public ResultUtil getById(@PathVariable("id")String id) {
        return ResultUtil.success(service.getUser(id,null));
    }

    /**
     * 新增
     */
    @Log(title = "新增用户")
    @PostMapping("/insert")
    @SaCheckPermission("system:user:add")
    public ResultUtil insert(@RequestBody SysUser user) throws NoSuchAlgorithmException, InvalidKeySpecException {
        if (service.checkUserNameAndPhone(user.getUserName(), user.getId())) {
            return ResultUtil.error("用户名已存在");
        }
        String password = RSAUtil.decrypt(user.getPassword());// 密码私钥解密
        String salt = EncryptionUtil.generateSalt();
        // 盐值加密
        password = EncryptionUtil.getEncryptedPassword(password, salt);
        user.setSalt(salt);
        user.setPassword(password);
        user.setId(IdUtil.getSnowflakeNextIdStr());
        service.save(user);
        // 保存用户与角色关联
        service.insertUserRole(user.getId(),user.getRoleIds());
        return ResultUtil.success();
    }

    /**
     * 修改用户
     */
    @Log(title = "修改用户")
    @PostMapping("/update")
    @SaCheckPermission("system:user:update")
    public ResultUtil update(@RequestBody @Validated SysUser user) {
        if (service.checkUserNameAndPhone(user.getUserName(), user.getId())) {
            return ResultUtil.error("用户名已存在");
        }
        service.updateById(user);
        SysUser currentUser = service.getCurrentUser();
        if (user.getId().equals(currentUser.getId())){
            SysUser userById = service.getUser(user.getId(),null);
            service.setDataScope(userById); // 设置用户的数据范围查询条件
            StpUtil.getSession().set("user",userById);
        }
        // 保存用户与角色关联
        service.insertUserRole(user.getId(),user.getRoleIds());
        return ResultUtil.success();
    }

    /**
     * 删除用户
     */
    @Log(title = "删除用户")
    @DeleteMapping("/delete/{id}")
    @SaCheckPermission("system:user:delete")
    public ResultUtil delete(@PathVariable("id")String id) {
        String [] ids = Convert.toStrArray(id);
        for (String userId : ids) {
            service.removeById(userId);
            //删除用户时，同时删除用户角色关联
            service.insertUserRole(userId,new String[0]);
        }
        return ResultUtil.success();
    }

    /**
     * 修改密码
     */
    @Log(title = "修改密码")
    @PostMapping("/updatePassword")
    public ResultUtil updatePassword(String oldPassword,String newPassword,String userId) throws InvalidKeySpecException, NoSuchAlgorithmException {
        //私钥解密
        oldPassword = RSAUtil.decrypt(oldPassword);
        newPassword = RSAUtil.decrypt(newPassword);
        if (StrUtil.isEmpty(oldPassword) || StrUtil.isEmpty(newPassword)){
            return ResultUtil.error("数据解密失败");
        }
        if (BaseConstant.initPassword.equals(newPassword)){
            return ResultUtil.error("新密码不可与初始密码相同");
        }
        SysUser user = service.getById(userId);
        //对旧密码进行加密对比
        boolean authenticate = EncryptionUtil.authenticate(oldPassword, user.getPassword(), user.getSalt());
        if (!authenticate){
            return ResultUtil.error("旧密码错误");
        }
        String salt = EncryptionUtil.generateSalt();
        String password = EncryptionUtil.getEncryptedPassword(newPassword, salt);
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("password", password);
        updateWrapper.set("salt", salt);
        updateWrapper.set("update_pwd_time", LocalDateTime.now());
        updateWrapper.eq("id",user.getId());
        service.update(updateWrapper);
        return ResultUtil.success();
    }

    /**
     * 上传头像
     */
    @Log(title = "上传头像")
    @PostMapping("/upload")
    public ResultUtil upload(@RequestParam MultipartFile file) throws IOException {
        String dateStr = LocalDateTimeUtil.format(LocalDateTime.now(),"yyyyMMdd-HHmmss");
        String fileName = file.getOriginalFilename();
        String filePath = path + dateStr;
        UpDownUtil.saveFile(file, filePath, fileName);
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("picture",filePath+ "/" + fileName);
        updateWrapper.eq("id", String.valueOf(StpUtil.getLoginId()));
        service.update(updateWrapper);
        return ResultUtil.success(filePath+ "/" + fileName);
    }

    /**
     * 导出word或pdf
     */
    @GetMapping("/exportWordOrPdf")
    @SaCheckPermission("system:user:view")
    public ResultUtil exportWordOrPdf(SysQuery query, boolean isPdf, HttpServletResponse response) {
        try {
            File zip = service.exportWordOrPdfZIP(query,"用户档案V1.1.0",isPdf);
            UpDownUtil.download(zip,response); // 将临时文件下载到浏览器
            FileUtil.del(zip.getParentFile()); // 下载完之后将临时文件删除
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.error("导出失败");
        }
        return ResultUtil.success();
    }

}
